package com.wrial.seckill.service.impl;
/*
 * @Author  Wrial
 * @Date Created in 14:33 2020/4/6
 * @Description
 */

import com.wrial.seckill.dao.OrderDOMapper;
import com.wrial.seckill.dao.SequenceDOmapper;
import com.wrial.seckill.dataobject.OrderDO;
import com.wrial.seckill.dataobject.SequenceDO;
import com.wrial.seckill.error.CustomizeErrorCode;
import com.wrial.seckill.error.CustomizeException;
import com.wrial.seckill.service.ItemService;
import com.wrial.seckill.service.OrderService;
import com.wrial.seckill.service.UserService;
import com.wrial.seckill.service.model.ItemModel;
import com.wrial.seckill.service.model.OrderModel;
import com.wrial.seckill.service.model.UserModel;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private ItemService itemService;
    @Autowired
    private UserService userService;
    @Autowired
    private SequenceDOmapper sequenceDOmapper;
    @Autowired
    private OrderDOMapper orderDOMapper;

    //1. 校验下单状态（正确性）
    //2. 对库存修改（落单减库存）  还有一种方式是支付减库存（这种不好控制超卖等操作）
    //3. 订单入库
    //4. 返回前端
    //1.校验下单状态,下单的商品是否存在，用户是否合法，购买数量是否正确
    @Override
    @Transactional
    public OrderModel createOrder(Integer userId, Integer itemId, Integer promoId, Integer amount) {
        //1.校验下单状态,下单的商品是否存在，用户是否合法，购买数量是否正确
        ItemModel itemModel = itemService.getItemById(itemId);
        if (itemModel == null) {
            throw new CustomizeException(CustomizeErrorCode.PARAMETER_VALIDATION_ERROR.setMessage("商品信息不存在"));
        }

        UserModel userModel = userService.getUserById(userId);
        if (userModel == null) {
            throw new CustomizeException(CustomizeErrorCode.PARAMETER_VALIDATION_ERROR.setMessage("用户信息不存在"));

        }
        if (amount <= 0 || amount > 99) {
            throw new CustomizeException(CustomizeErrorCode.PARAMETER_VALIDATION_ERROR.setMessage("数量信息不正确"));
        }

        //校验活动信息
        if (promoId != null) {
            //（1）校验对应活动是否存在这个适用商品
            if (promoId.intValue() != itemModel.getPromoModel().getId()) {
                throw new CustomizeException(CustomizeErrorCode.PARAMETER_VALIDATION_ERROR.setMessage("活动信息不正确"));
                //（2）校验活动是否正在进行中
            } else if (itemModel.getPromoModel().getStatus().intValue() != 2) {
                throw new CustomizeException(CustomizeErrorCode.PARAMETER_VALIDATION_ERROR.setMessage("活动信息还未开始"));
            }

        }

        //2.落单减库存
        boolean result = itemService.decreaseStock(itemId, amount);
        if (!result) {
            throw new CustomizeException(CustomizeErrorCode.STOCK_NOT_ENOUGH);
        }

        //3.订单入库
        OrderModel orderModel = new OrderModel();
        orderModel.setUserId(userId);
        orderModel.setItemId(itemId);
        orderModel.setAmount(amount);
        if (promoId != null) {
            orderModel.setItemPrice(itemModel.getPromoModel().getPromoItemPrice());
        } else {
            orderModel.setItemPrice(itemModel.getPrice());
        }
        orderModel.setPromoId(promoId);
        orderModel.setOrderPrice(orderModel.getItemPrice().multiply(new BigDecimal(amount)));

        //生成交易流水号,订单号
        orderModel.setId(generateOrderNo());
        OrderDO orderDO = convertFromOrderModel(orderModel);
        orderDOMapper.insert(orderDO);

        //加上商品的销量
        itemService.increaseSales(itemId, amount);
        //4.返回前端
        return orderModel;
    }

    //订单信息16位：8位时间信息+6位自增序列+2位分库分表位
    // 使用Requires new 是因为就算上面的操作失败了（回滚），这个sequence也不能用了
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    protected String generateOrderNo() {
        //订单号有16位
        StringBuilder stringBuilder = new StringBuilder();
        //前8位为时间信息，年月日
        LocalDateTime now = LocalDateTime.now();
        String nowDate = now.format(DateTimeFormatter.ISO_DATE).replace("-", "");
        stringBuilder.append(nowDate);

        //中间6位为自增序列
        //获取当前sequence
        int sequence = 0;
        SequenceDO sequenceDO = sequenceDOmapper.getSequenceByName("order_info");
        sequence = sequenceDO.getCurrentValue();
        // 使用当前值+步长  存在的问题就是当这六位使用完毕后造成越界
        sequenceDO.setCurrentValue(sequenceDO.getCurrentValue() + sequenceDO.getStep());
        // 更新sequence
        sequenceDOmapper.updateById(sequenceDO);
        String sequenceStr = String.valueOf(sequence);
        for (int i = 0; i < 6 - sequenceStr.length(); i++) {
            stringBuilder.append(0);
        }
        stringBuilder.append(sequenceStr);


        //最后2位为分库分表位,暂时写死
        stringBuilder.append("00");
        return stringBuilder.toString();
    }

    private OrderDO convertFromOrderModel(OrderModel orderModel) {
        if (orderModel == null) {
            return null;
        }
        OrderDO orderDO = new OrderDO();
        BeanUtils.copyProperties(orderModel, orderDO);
        orderDO.setItemPrice(orderModel.getItemPrice().doubleValue());
        orderDO.setOrderPrice(orderModel.getOrderPrice().doubleValue());
        return orderDO;
    }

}
